
#include <conio.h>
#include <graphics.h>

#define High 480  // 游戏画面尺寸
#define Width 640
#define brick_num  10//砖块数量

// 全局变量
int ball_x,ball_y; // 小球的坐标
int ball_vx,ball_vy; // 小球的速度
int radius;     // 小球的半径
int bar_x,bar_y;//挡板中心坐标
int barLength;//挡板长度
int brick[brick_num]; //存在砖块为1，不存在为2
int brick_high,brick_width;//砖块高和宽
MOUSEMSG m;//定义鼠标信息


void startup()  // 数据初始化
{
	ball_x = Width/2;
	ball_y = High/2;
	ball_vx = 1;
	ball_vy = 1;
	radius = 20;
	bar_x=High-50;
	bar_y=Width/2;
	barLength=80;
	int i;
	for(i=0;i<brick_num;i++){
		brick[i]=1;
	}
	//计算砖块高和宽
	brick_high=High/brick_num;
	brick_width=Width/brick_num;

	
	initgraph(Width, High);
	BeginBatchDraw();//开始绘图
}

void clean()  // 覆盖画面
{
	// 绘制黑线、黑色填充的圆
	setcolor(BLACK);
	setfillcolor(BLACK);
	fillcircle(ball_y, ball_x, radius);
	//画黑色挡板
	setcolor(BLACK);
	setfillcolor(BLACK);
	bar(bar_y-barLength,bar_x,bar_y+barLength,bar_x+20);
	//画黑色砖块
	int i,brick_left,brick_top,brick_right,brick_bottom;//砖块边界
	for(i=0;i<brick_num;i++){
		brick_left=i*brick_width;
		brick_top=0;
		brick_right=brick_left+brick_width;
		brick_bottom=brick_high;
		
		//砖块存在，打印砖块
		if(! brick[i]){
			setcolor(BLACK);
			setfillcolor(BLACK);
			fillrectangle(brick_left,brick_top,brick_right,brick_bottom);
		}
		
	}
}	

void show()  // 显示画面
{
	// 绘制黄线、红色填充的圆
	setcolor(YELLOW);
	setfillcolor(RED);
	fillcircle(ball_y, ball_x, radius);
	
	//画挡板
	setcolor(BLUE);
	setfillcolor(BLUE);
	bar(bar_y-barLength,bar_x,bar_y+barLength,bar_x+20);

	//画砖块
	int i,brick_left,brick_top,brick_right,brick_bottom;//砖块边界
	for(i=0;i<brick_num;i++){
		brick_left=i*brick_width;
		brick_top=0;
		brick_right=brick_left+brick_width;
		brick_bottom=brick_high;

		//砖块存在，打印砖块
		if(brick[i]){
			setcolor(WHITE);
			setfillcolor(GREEN);
			fillrectangle(brick_left,brick_top,brick_right,brick_bottom);
		}

	}

	FlushBatchDraw();//结束绘图
	
	Sleep(1);// 延时
}	

void updateWithoutInput()  // 与用户输入无关的更新
{
	// 小球移动
	ball_x = ball_x + ball_vx;
	ball_y = ball_y + ball_vy;
	
	//碰到边界反弹
	if (( ball_x-radius <=0 )||( ball_x +radius>= High))
		ball_vx = -ball_vx;
	if (( ball_y-radius <=0 )||( ball_y +radius>= Width ))
		ball_vy = -ball_vy;	

	//碰到挡板反弹
	if( ball_x+radius >= bar_x ){
		if(ball_y>=bar_y-barLength+5  && ball_y<=bar_y+barLength-5){
			ball_vx = -ball_vx;
		}
	}

	//小球是否碰撞某个砖块
	int i,brick_left,brick_right,brick_bottom;
	for(i=0;i<brick_num;i++){
		if( brick[i]){  //这个砖块存在时开始判断

			//获取这个砖块的左右下边界信息
			brick_left=i*brick_width;
			brick_right=brick_left+brick_width;
			brick_bottom=brick_high;

			if(ball_x-radius<=brick_bottom){
				if(ball_y>=brick_left && ball_y<=brick_right){
					brick[i]=0; //砖块不存在了
					ball_vx=-ball_vx;  //小球反弹
				}
				
			}
		}
	}

	//限制挡板的移动范围
	if( bar_y-barLength<=0){
		bar_y=barLength;
	}
	if(bar_y+barLength>=Width){
		bar_y=Width-barLength;
	}
	if(bar_x+20>High){
		bar_x=High-20;
	}
	if(bar_x<High/2){
		bar_x=High/2;
	}
}

void updateWithInput()  // 与用户输入有关的更新
{	
	char move;
	if(kbhit())//键盘输入
	{
		move = getch();
		//挡板移动
		if(move=='a'){
			bar_y-=10;
		}
		if(move=='d'){
			bar_y+=10;
		}
		if(move=='w'){
			bar_x-=5;
		}
		if(move=='s'){
			bar_x+=5;
		}

	}

	//鼠标输入
	if(MouseHit()){
	m = GetMouseMsg();//获取一条鼠标消息
	if(m.uMsg==WM_MOUSEMOVE){//如果鼠标移动
		//挡板位置随鼠标移动
		bar_x=m.y;
		bar_y=m.x;
	}
	}

}

void gameover()//游戏结束
{
	EndBatchDraw();
	closegraph();
}

int main()
{
	startup();  // 数据初始化	
	while (1)  //  游戏循环执行
	{
		clean();  // 把之前绘制的小球覆盖（清）
		updateWithoutInput();  // 与用户输入无关的更新
		updateWithInput();     // 与用户输入有关的更新
		show();  // 显示新画面
	}
	gameover();     // 游戏结束、后续处理
	return 0;
}

